package accesoBD;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * Clase que representa la interacción de un técnico con la base de datos.
 * @version 1.2
 * @author Juan Manuel Rodríguez González
 */
public class QuerySupervisor extends QueryTecnico {
    
    /**
     * Constructor de QuerySupervisor. Al heredar de QueryUsuario hereda sus parámetros.
     * @param idUsuario String que contiene el id del usuario.
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    public QuerySupervisor(String idUsuario) throws SQLException, ClassNotFoundException {
        super(idUsuario);
    }

    /**
     * Devuelve los partes que ha asignado dicho supervisor.
     * @return Un objeto resultSet que contiene los partes obtenidos.
     * @throws SQLException
     */
    public ResultSet getPartesAsignados() throws SQLException {
        return QuerySupervisor.db.selectEscrito("select * from asigna where id_usuario_sup="+idUsuario);
    }

    /**
     * Devuelve los partes que están abiertos.
     * @return Un objeto resultSet que contiene los partes obtenidos.
     * @throws SQLException
     */
    public ResultSet getPartesAbiertos() throws SQLException {
        return QuerySupervisor.db.selectEscrito("select asi.id_parte from asigna asi, parte_incidencia pa where pa.estado='asignado' and pa.id_parte= asi.id_parte and pa.fecha_cierre is null group by asi.id_parte order by asi.id_parte asc");
    }

    /**
     * Reasigna un parte a un técnico.
     * @param idUsuarioTec Identificador del técnico para el que asignamos el parte.
     * @param idParte Identificador del parte de usuario.
     * @return Un boolean informando del éxito de la reasignación.
     * @throws SQLException
     */
    public boolean reasignarParte(String idUsuarioTec, String idParte) throws SQLException {
        
        PreparedStatement ps = QuerySupervisor.db.getCon().prepareStatement("insert into asigna (id_usuario_sup, id_usuario_tec, id_parte, fecha) values (?,?,?, current_timestamp)");
        ps.clearParameters();
        ps.setString(1, idUsuario);
        ps.setString(2, idUsuarioTec);
        ps.setString(3, idParte);
        int s = ps.executeUpdate();

        return (s > 0);
    }
    
    /**
     * Registra un nuevo aparato en la base de datos.
     * @param nombre Nombre del dispositivo.
     * @param codigoPub Codigo público del dispositivo.
     * @param condigoInt
     * @param marca Marca del dispositivo.
     * @param modelo Modelo del dispositivo.
     * @param color Color del dispositivo.
     * @param garantia Garantía del dispositivo.
     * @param ubicacion Identificador de la ubicación del dispositivo.
     * @return Un boolean informando del éxito de la creación.
     * @throws SQLException
     */
    public boolean crearAparato(String nombre, String codigoPub, String condigoInt, String marca, String modelo, String color, String garantia, String ubicacion) throws SQLException {
        PreparedStatement ps = QuerySupervisor.db.getCon().prepareStatement("insert into aparato values (aparato_seq.nextval, ?, ?, ?, ?, ?, ?, to_char(to_date(sysdate)), ?, ?)");
        ps.clearParameters();
        ps.setString(1, nombre);
        ps.setString(2, codigoPub);
        ps.setString(3, condigoInt);
        ps.setString(4, marca);
        ps.setString(5, modelo);
        ps.setString(6, color);
        ps.setString(7, garantia);
        ps.setString(8, ubicacion);
        int s = ps.executeUpdate();

        return (s > 0);
    }
    
    /**
     * Añade una ubicación a la base de datos.
     * @param idArea Identificador del área.
     * @param sala Nombre de la sala.
     * @param planta Número de la planta.
     * @param pasillo Número del pasillo.
     * @return Un boolean informando del éxito de la creación.
     * @throws SQLException
     */
    public boolean addUbicacion(String idArea, String sala, String planta, String pasillo) throws SQLException {
        
        PreparedStatement ps = QuerySupervisor.db.getCon().prepareStatement("insert into ubicacion values (ubicacion_seq.nextval, ?, ?, ?, ?)");
        ps.clearParameters();
        ps.setString(1, idArea);
        ps.setString(2, sala);
        ps.setString(3, planta);
        ps.setString(4, pasillo);
        int s = ps.executeUpdate();

        return (s > 0);
    }
    
    /**
     * Externaliza una actuación.
     * @param CIFempresa cif de la empresa.
     * @param idParte identificador del parte que se externaliza.
     * @param nota nota de la actuación.
     * @return Un boolean informando del éxito de la operación.
     * @throws SQLException
     */
    public boolean externalizarActuacion(String CIFempresa, String idParte, String nota) throws SQLException {
            //Para rellenar el dispositivo
            Statement stmt = QuerySupervisor.db.getCon().createStatement();
            String consulta1 = "select descripcion_general,id_aparato from parte_incidencia WHERE id_parte=" + idParte;
            System.out.println(consulta1);
            ResultSet rset = stmt.executeQuery(consulta1);
            rset.next();
            
            String diagnostico = rset.getString(1);
            int aparato = rset.getInt(2);

            consulta1 = "select codigo_publico, marca, modelo from aparato where id_aparato=" + aparato;
            System.out.println(consulta1);
            rset = stmt.executeQuery(consulta1);
            rset.next();
            String nombre = rset.getString(1);
            String marca = rset.getString(2);
            String modelo = rset.getString(3);

            PreparedStatement ps;

            boolean s1 = ((QueryTecnico) this).añadirIncidencia(Integer.parseInt(idParte), diagnostico);

            //Crear actuación
            ps = QuerySupervisor.db.getCon().prepareStatement("insert into actuacion "
                    + "(id_actuacion,descripcion) "
                    + "values (actuacion_seq.nextval, ?)");
            ps.clearParameters();
            ps.setString(1, nota);
            System.out.println(ps.toString());
            int s3 = ps.executeUpdate();

            //Crear tupla en supone
            consulta1 = "select actuacion_seq.currval from dual";
            rset = stmt.executeQuery(consulta1);
            rset.next();
            int ac = rset.getInt(1);
            ps = QuerySupervisor.db.getCon().prepareStatement("insert into supone "
                    + "(id_incidencia, id_actuacion) "
                    + "values (incidencia_seq.currval,actuacion_seq.currval)");
            ps.clearParameters();
            System.out.println(ps.toString());
            int s4 = ps.executeUpdate();


            consulta1 = "select id_empresa_externa from empresa_externa where cif=" + CIFempresa;
            System.out.println(consulta1);
            rset = stmt.executeQuery(consulta1);
            rset.next();
            String id_empresa = rset.getString(1);

            //Crear subcontrata            
            ps = QuerySupervisor.db.getCon().prepareStatement("insert into subcontrata "
                    + "(id_usuario, id_actuacion, id_empresa_externa, fecha_entrega, presupuesto) "
                    + "values (?,?,?,to_char(to_date(sysdate)),?)");
            ps.clearParameters();
            ps.setInt(1, 8);
            ps.setInt(2, ac);
            ps.setString(3, id_empresa);
            ps.setInt(4, 0);
            int s5 = ps.executeUpdate();
            
            ps = QuerySupervisor.db.getCon().prepareStatement("update parte_incidencia set estado='subcontratado' where id_parte=?");
            ps.clearParameters();
            ps.setString(1, idParte);
            int s6 = ps.executeUpdate();

        return (s1 && s3 > 0 && s4 > 0 && s5 > 0 && s6 > 0);
    }
    
    /**
     * Devuelve los nombre de todos los técnicos registrados.
     * @return Un objeto resultSet que contiene los técnicos registrados.
     * @throws SQLException
     */
    public ResultSet getNombreTecnicos() throws SQLException {
        return QuerySupervisor.db.selectEscrito("select t.id_usuario, u.nombre from usuario u, tecnico t where u.id_usuario=t.id_usuario");
    }
    
    /**
     * Devuelve el usuario que creó un determinado parte.
     * @param idParte identificador del parte.
     * @return Un objeto resultSet que contiene los datos del usuario.
     * @throws SQLException
     */
    public ResultSet getUsuario_Parte(String idParte) throws SQLException {
        return QuerySupervisor.db.selectEscrito("select u.id_usuario, u.nombre, u.email, p.id_parte from usuario u,parte_incidencia p where u.id_usuario=p.id_usuario and p.id_parte='"+idParte+"'");
    }
    
    /**
     * Devuelve el técnico que actualmente es responsable de un determinado parte.
     * @param idParte identificador del parte.
     * @return Un objeto resultSet que contiene los datos del técnico.
     * @throws SQLException
     */
    public ResultSet getTecnico_Parte(String idParte) throws SQLException {
        return QuerySupervisor.db.selectEscrito("select * from (select id_usuario_tec from asigna where id_parte='"+idParte+"' order by fecha desc) where rownum<=1");
    }
    
    /**
     * Devuelve las incidencias de un parte.
     * @param idParte identificador del parte.
     * @return Un objeto resultSet que contiene las incidencias.
     * @throws SQLException
     */
    public ResultSet getIncidencia_Parte(String idParte) throws SQLException {
        return QuerySupervisor.db.selectEscrito("select id_incidencia from contiene where id_parte=" + idParte);
    }
    
    /**
     * Devuelve el diagnóstico de una cierta incidencia.
     * @param id_incidencia identificador de la incidencia.
     * @return Un objeto resultSet que contiene los partes obtenidos.
     * @throws SQLException
     */
    public ResultSet getCausa_Incidencia(String id_incidencia) throws SQLException {
        return QuerySupervisor.db.selectEscrito("select diagnostico from incidencia where id_incidencia=" + id_incidencia);
    }
    
    /**
     * Devuelve las actuaciones de una incidencia.
     * @param id_incidencia identificador de la incidencia.
     * @return Un objeto resultSet que contiene las actuaciones obtenidas.
     * @throws SQLException
     */
    public ResultSet getActuacion_Incidencia(String id_incidencia) throws SQLException {
        return QuerySupervisor.db.selectEscrito("select id_actuacion from supone where id_incidencia=" + id_incidencia);
    }
    
    /**
     * Devuelve los tiempos y el coste de una cierta actuación.
     * @param id_actuacion identificador de la actuación.
     * @return Un objeto resultSet que contiene los datos.
     * @throws SQLException
     */
    public ResultSet getTiempo_Actuacion(String id_actuacion) throws SQLException {
        return QuerySupervisor.db.selectEscrito("select tiempo_estimado, tiempo_invertido, coste from actuacion where id_actuacion=" + id_actuacion);
    }
    
    /**
     * Devuelve la empresa a la que se ha subcontratado una actuación.
     * @param id_actuacion identificador de la actuación.
     * @return Un objeto resultSet que contiene los identificadores de empresa.
     * @throws SQLException
     */
    public ResultSet getEmpresa_Actuacion(String id_actuacion) throws SQLException {
        return QuerySupervisor.db.selectEscrito("select id_empresa_externa, fecha_entrega from subcontrata where id_actuacion=" + id_actuacion);
    }
    
    /**
     * Devuelve el nombre de una cierta empresa.
     * @param id_empresa identificador de la empresa.
     * @return Un objeto resultSet que contiene los nombres de las empresas.
     * @throws SQLException
     */
    public ResultSet getNombre_Empresa(String id_empresa) throws SQLException {
        return QuerySupervisor.db.selectEscrito("select nombre from empresa_externa where id_empresa_externa=" + id_empresa);
    }
    
    /**
     * Devuelve el código público y la ubicación de un aparato.
     * @param id_aparato identificador del aparato.
     * @return Un objeto resultSet que contiene los códigos de los aparatos.
     * @throws SQLException
     */
    public ResultSet getCodigo_Aparato(String id_aparato) throws SQLException {
        return QuerySupervisor.db.selectEscrito("select codigo_publico, id_ubicacion from aparato where id_aparato=" + id_aparato);
    }
    
    /**
     * Devuelve el nombre de la sala a la que pertenece una cierta ubicación.
     * @param id_ubicacion identificador de la ubicación.
     * @return Un objeto resultSet que contiene los nombres de las salas.
     * @throws SQLException
     */
    public ResultSet getSala_Ubicacion(String id_ubicacion) throws SQLException {
        return QuerySupervisor.db.selectEscrito("select sala from ubicacion where id_ubicacion=" + id_ubicacion);
    }
    
    /**
     * Devuelve los identificadores de todos los técnicos.
     * @return Un objeto resultSet que contiene los datos de los técnicos.
     * @throws SQLException
     */
    public ResultSet getId_Tecnico() throws SQLException {
        return QuerySupervisor.db.selectEscrito("select id_usuario from tecnico");
    }
    
    /**
     * Devuelve todos los datos de todas las empresas externas.
     * @return Un objeto resultSet que contiene las empresas externas.
     * @throws SQLException
     */
    public ResultSet getAllEmpresa() throws SQLException {
        return QuerySupervisor.db.selectEscrito("select * from empresa_externa");
    }
    
    /**
     * Devuelve el identificador de un cierto área de trabajo.
     * @param area nombre del área de trabajo.
     * @return Un objeto resultSet que contiene los identificadores de áreas de trabajo.
     * @throws SQLException
     */
    public ResultSet getIdArea(String area) throws SQLException {
        return QuerySupervisor.db.selectEscrito("select id_area from area_de_trabajo where descripcion='" + area + "'");
    }
    
    /**
     * Devuelve el identificador de un cierto técnico.
     * @param nombre nombre del usuario técnico.
     * @return Un objeto resultSet que contiene los partes obtenidos.
     * @throws SQLException
     */
    public ResultSet getIdTecnico(String nombre) throws SQLException {
        return QuerySupervisor.db.selectEscrito("select u.id_usuario from tecnico tec, usuario u where u.nombre='"+nombre+"' and tec.id_usuario=u.id_usuario");
    }
  
    /**
     * Devuelve los parte de los que es responsable un cierto técnico.
     * @param idTecnico identificador del técnico.
     * @return Un objeto resultSet que contiene los partes obtenidos.
     * @throws SQLException
     */
    public ResultSet getPartesTecnico(String idTecnico) throws SQLException {
        return QuerySupervisor.db.selectEscrito("select asi.id_parte from asigna asi, parte_incidencia pa where asi.id_usuario_tec='"+idTecnico+"'and asi.id_parte = pa.id_parte and pa.estado = 'asignado' and asi.fecha >= all (select asi2.fecha from asigna asi2 where asi.id_parte=asi2.id_parte) order by asi.id_parte");
    }
    
    /**
     * Devuelve los partes que están externalizados.
     * @return Un objeto resultSet que contiene los partes externalizados.
     * @throws SQLException
     */
    public ResultSet getPartesExternos() throws SQLException{
        return QuerySupervisor.db.selectEscrito("select id_parte from (select con.id_parte, su.id_incidencia, su.id_actuacion from actuacion ac, subcontrata sub, supone su, contiene con, parte_incidencia pa where ac.id_actuacion = sub.id_actuacion and su.id_actuacion = ac.id_actuacion and su.id_incidencia = con.id_incidencia and pa.id_parte = con.id_parte and pa.estado = 'subcontratado') group by id_parte order by id_parte asc");
    }
}